package com.masiyi.aliyun.template;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.PutObjectResult;
import com.masiyi.aliyun.config.AliyunOssProperties;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * @author masiyi
 */
@Slf4j
public class AliyunTemplate {
    private OSS oss;
    private AliyunOssProperties aliyunOssProperties;

    public AliyunTemplate(OSS oss, AliyunOssProperties aliyunOssProperties) {
        this.oss = oss;
        this.aliyunOssProperties = aliyunOssProperties;
    }

    /**
     * 上传文件
     *
     * @param txt 文件内容
     * @param objectName 文件标题（需要包含后缀）
     */
    public PutObjectResult putObject(String txt, String objectName) {
        try {
            return oss.putObject(aliyunOssProperties.getBucketName(), objectName, new ByteArrayInputStream(txt.getBytes()));
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
           log.error(ce.getMessage(),ce);
        }
        return null;
    }

    /**
     * 上传图片
     */
    public PutObjectResult putImage(InputStream inputStream, String fileName) {

        try {
            return oss.putObject(aliyunOssProperties.getBucketName(), fileName, inputStream);
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
            log.error(ce.getMessage(),ce);
        }
        return null;
    }

    /**
     * 创建存储空间。
     */
    public Bucket createBucket(String bucketName) {
        Bucket bucket = null;
        try {
            // 创建存储空间。
            bucket = oss.createBucket(bucketName);
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
            log.error(ce.getMessage(),ce);
        }
        return bucket;
    }


    /**
     * 下载文件 以下代码用于通过流式下载方式从OSS下载文件。
     */
    public void getObject(String bucketName, String objectName) {

        try {
            // 调用ossClient.getObject返回一个OSSObject实例，该实例包含文件内容及文件元数据。
            OSSObject ossObject = oss.getObject(bucketName, objectName);
            // 调用ossObject.getObjectContent获取文件输入流，可读取此输入流获取其内容。
            InputStream content = ossObject.getObjectContent();
            if (content != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                while (true) {
                    String line = reader.readLine();
                    if (line == null) {
                        break;
                    }
                    System.out.println("\n" + line);
                }
                // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
                content.close();
            }
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
            log.error(ce.getMessage(),ce);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 列举文件
     * 以下代码用于列举存储空间bucket下的文件。默认列举100个文件。
     */
    public ObjectListing listObjects(String bucketName) {
        ObjectListing objectListing = null;
        try {
            // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
            objectListing = oss.listObjects(bucketName);
            // objectListing.getObjectSummaries获取所有文件的描述信息。
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                System.out.println(" - " + objectSummary.getKey() + "  " +
                        "(size = " + objectSummary.getSize() + ")");
            }
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
            log.error(ce.getMessage(),ce);
        }
        return objectListing;
    }


    /**
     * 删除文件
     * 以下代码用于删除指定文件
     */
    public void deleteObject(String bucketName, String objectName) {
        try {
            // 删除文件。
            oss.deleteObject(bucketName, objectName);
        } catch (OSSException oe) {
            log.error(oe.getMessage(),oe);
        } catch (ClientException ce) {
            log.error(ce.getMessage(),ce);
        }
    }

    
}
